// ------------------------------------------------------------------------------------------
// Licensed by Interprise Solutions.
// http://www.InterpriseSolutions.com
// For details on this license please visit  the product homepage at the URL above.
// THE ABOVE NOTICE MUST REMAIN INTACT.
// ------------------------------------------------------------------------------------------
using System;
using System.IO;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Data.SqlClient;
using System.Web;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Xml;
using System.Xml.Serialization;
using System.Xml.Xsl;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters;
using System.Runtime.Serialization.Formatters.Soap;

namespace InterpriseSuiteEcommerceCommon
{
    [Serializable]
    public class Rating : ISerializable
    {
        public enum RatingOption
        {
            Terrible = 1,
            Bad = 2,
            OK = 3,
            Good = 4,
            Great = 5
        }
     
        public enum RatingSortOrder
        {
            HelpfulToLessHelpful = 1,
            LessHelpfulToHelpful = 2,
            NewToOld = 4,
            OldToNew = 8,
            HighToLow = 16,
            LowToHigh = 32
        }

        public static RatingOption TryParse(int rating)
        {
            if (rating > 0 && rating < 6)
            {
                return (RatingOption)rating;
            }

            return RatingOption.OK;
        }

        public Rating()
        {
        }

        public Rating(string itemCode, RatingOption rate, string comment, DateTime createdOn, string customerCode, string customerSalutationCode, string customerFirstName,
            string customerLastName, string contactCode, string contactSalutationCode, string contactFirstName,
            string contactLastName)
            : this(itemCode, rate, comment, createdOn, 0, 0, customerCode, customerSalutationCode, customerLastName, customerFirstName, contactCode, contactSalutationCode, contactLastName, contactFirstName) { }

        private const string ITEM_CODE_PROPERTY = "ItemCode";        
        private const string RATE_PROPERTY = "Rate";
        private const string COMMENT_PROPERTY = "Comment";
        private const string FOUND_HELPFUL = "FoundHelpful";
        private const string HELPFUL_COUNT_COMMENT = "HelpfulCount";
        private const string NOTHELPFUL_COUNT_COMMENT = "NotHelpfulCount";
        private const string CREATED_ON_COMMENT = "CreatedOn";
        private const string CUSTOMER_CODE_PROPERTY = "CustomerCode";
        private const string CUSTOMER_SALUTATIONCODE_PROPERTY = "CustomerSalutationCode";
        private const string CUSTOMER_LASTNAME_PROPERTY = "CustomerLastName";
        private const string CUSTOMER_FIRSTNAME_PROPERTY = "CustomerFirstName";
        private const string CONTACT_CODE_PROPERTY = "ContactCode";
        private const string CONTACT_SALUTATIONCODE_PROPERTY = "ContactSalutationCode";
        private const string CONTACT_LASTNAME_PROPERTY = "ContactLastName";
        private const string CONTACT_FIRSTNAME_PROPERTY = "ContactFirstName";
        private const string ITEM_COUNTER = "Counter";


        #region Serialization Support

        public Rating(SerializationInfo info, StreamingContext context)
        {
            _itemCode = info.GetString(ITEM_CODE_PROPERTY);
            _rate = (RatingOption)info.GetInt32(RATE_PROPERTY);
            _comment = info.GetString(COMMENT_PROPERTY);
            _foundHelpful = info.GetString(FOUND_HELPFUL);
            _helpfulCount = info.GetInt32(HELPFUL_COUNT_COMMENT);
            _notHelpfulCount = info.GetInt32(NOTHELPFUL_COUNT_COMMENT);
            _createdOn = info.GetDateTime(CREATED_ON_COMMENT);
            _customerCode = info.GetString(CUSTOMER_CODE_PROPERTY);
            _customerSalutationCode = info.GetString(CUSTOMER_SALUTATIONCODE_PROPERTY);
            _customerLastName = info.GetString(CUSTOMER_LASTNAME_PROPERTY);
            _customerFirstName = info.GetString(CUSTOMER_FIRSTNAME_PROPERTY);
            _contactCode = info.GetString(CONTACT_CODE_PROPERTY);
            _contactSalutationCode = info.GetString(CONTACT_SALUTATIONCODE_PROPERTY);
            _contactLastName = info.GetString(CONTACT_LASTNAME_PROPERTY);
            _contactFirstName = info.GetString(CONTACT_FIRSTNAME_PROPERTY);
        }

        [System.Security.SecurityCritical]
        public void GetObjectData(SerializationInfo info, StreamingContext context)
        {
            info.AddValue(ITEM_CODE_PROPERTY, _itemCode);            
            info.AddValue(RATE_PROPERTY, _rate);
            info.AddValue(COMMENT_PROPERTY, _comment);
            info.AddValue(FOUND_HELPFUL, _foundHelpful);
            info.AddValue(HELPFUL_COUNT_COMMENT, _helpfulCount);
            info.AddValue(NOTHELPFUL_COUNT_COMMENT, _notHelpfulCount);
            info.AddValue(CREATED_ON_COMMENT, _createdOn);
            info.AddValue(CUSTOMER_SALUTATIONCODE_PROPERTY, _customerSalutationCode);
            info.AddValue(CUSTOMER_LASTNAME_PROPERTY, _customerLastName );
            info.AddValue(CUSTOMER_FIRSTNAME_PROPERTY, _customerFirstName );
        }

        #endregion

        internal Rating(string itemCode, RatingOption rate, string comment, DateTime createdOn, int helpfulCount, int notHelpfulCount, 
            string customerCode,string customerSalutationCode, string customerLastName, string customerFirstName,
            string contactCode, string contactSalutationCode, string contactLastName, string contactFirstName)
        {
            _itemCode = itemCode;
            _rate = rate;
            _comment = comment;
            _helpfulCount = helpfulCount;
            _notHelpfulCount = notHelpfulCount;
            _createdOn = createdOn;
            _customerCode = customerCode;
            _customerSalutationCode = customerSalutationCode;
            _customerLastName = customerLastName;
            _customerFirstName = customerFirstName;
            _contactCode = contactCode;
            _contactSalutationCode = contactSalutationCode;
            _contactLastName = contactLastName;
            _contactFirstName = contactFirstName;
        }

        #region Variable Declaration

        private string _itemCode;
        private RatingOption _rate;
        private string _comment;
        private string _foundHelpful;
        private int _helpfulCount;
        private int _notHelpfulCount;
        private DateTime _createdOn;
        private string _customerCode;
        private string _customerSalutationCode;
        private string _customerLastName;
        private string _customerFirstName;
        private string _contactCode;
        private string _contactSalutationCode;
        private string _contactLastName;
        private string _contactFirstName;


        #endregion

        #region Properties

        public string ItemCode
        {
            get { return _itemCode; }
            set { throw new NotSupportedException(); }
        }

        public string CustomerCode
        {
            get { return _customerCode; }
            set { throw new NotSupportedException(); }
        }

        public string ContactCode
        {
            get { return _contactCode; }
            set { throw new NotSupportedException(); }
        }

        public string CustomerSalutationCode
        {
            get { return _customerSalutationCode; }
            set { throw new NotSupportedException(); }
        }

        public string CustomerLastName
        {
            get { return _customerLastName ; }
            set { throw new NotSupportedException(); }
        }

        public string CustomerFirstName
        {
            get { return _customerFirstName; }
            set { throw new NotSupportedException(); }
        }

        public string ContactSalutationCode
        {
            get { return _contactSalutationCode; }
            set { throw new NotSupportedException(); }
        }

        public string ContactLastName
        {
            get { return _contactLastName; }
            set { throw new NotSupportedException(); }
        }

        public string ContactFirstName
        {
            get { return _contactFirstName; }
            set { throw new NotSupportedException(); }
        }
        

        [XmlIgnore()]
        public RatingOption Rate
        {
            get { return _rate; }
            set { throw new NotSupportedException(); }
        }

        [XmlElement(ElementName = "Rate")]
        public int ActualRating
        {
            get { return (int)_rate; }
            set { throw new NotSupportedException(); }
        }

        public string Comment
        {
            get { return _comment; }
            set { throw new NotSupportedException(); }
        }

        public int HelpfulCount
        {
            get { return _helpfulCount; }
            set { throw new NotSupportedException(); }
        }

        public int NotHelpfulCount
        {
            get { return _notHelpfulCount; }
            set { throw new NotSupportedException(); }
        }

        public DateTime CreatedOn
        {
            get { return _createdOn; }
            set { throw new NotSupportedException(); }
        }

        #endregion

        public void SynchronizeHelpfulCount(string itemcode)
        {
            using (SqlConnection con = new SqlConnection(DB.GetDBConn()))
            {
                using (SqlCommand cmdSync = new SqlCommand("EcommerceSynchronizeRatingCommentHelpfulness", con))
                {
                    cmdSync.CommandType = CommandType.StoredProcedure;

                    SqlParameter paramItemCode = new SqlParameter("@ItemCode", SqlDbType.NVarChar, 30);
                    SqlParameter paramWebsiteCode = new SqlParameter("@WebsiteCode", SqlDbType.NVarChar, 30);

                    paramItemCode.Value = DB.SQuote(itemcode);
                    paramWebsiteCode.Value = InterpriseHelper.ConfigInstance.WebSiteCode;

                    cmdSync.Parameters.Add(paramItemCode);
                    cmdSync.Parameters.Add(paramWebsiteCode);

                    con.Open();

                    using (IDataReader onCountUpdatedReader = cmdSync.ExecuteReader())
                    {
                        if (onCountUpdatedReader.Read())
                        {
                            // update the links
                            _helpfulCount = DB.RSFieldInt(onCountUpdatedReader, "FoundHelpful");
                            _notHelpfulCount = DB.RSFieldInt(onCountUpdatedReader, "FoundNotHelpful");
                        }
                    }
                }
            }
        }

        public void FilterBadWords()
        {
            // retrieve then scan....
        }

        public static Rating ByCustomer(Customer thisCustomer, string onItemCode)
        {
            Rating customerRating = null;

            using (SqlConnection con = new SqlConnection(DB.GetDBConn()))
            {
                using (SqlCommand cmdGetRating = new SqlCommand("EcommerceGetRating", con))
                {
                    cmdGetRating.CommandType = CommandType.StoredProcedure;

                    SqlParameter paramItemCode = new SqlParameter("@ItemCode", SqlDbType.NVarChar, 30);
                    SqlParameter paramCustomerCode = new SqlParameter("@CustomerCode", SqlDbType.NVarChar, 30);
                    SqlParameter paramWebsiteCode = new SqlParameter("@WebsiteCode", SqlDbType.NVarChar, 30);
                    SqlParameter paramContactCode = new SqlParameter("@ContactCode", SqlDbType.NVarChar, 30);

                    paramItemCode.Value = onItemCode;
                    paramCustomerCode.Value = thisCustomer.CustomerCode;
                    paramWebsiteCode.Value = InterpriseHelper.ConfigInstance.WebSiteCode;
                    paramContactCode.Value = thisCustomer.ContactCode;

                    cmdGetRating.Parameters.Add(paramItemCode);
                    cmdGetRating.Parameters.Add(paramCustomerCode);
                    cmdGetRating.Parameters.Add(paramWebsiteCode);
                    cmdGetRating.Parameters.Add(paramContactCode);

                    con.Open();

                    using (IDataReader reader = cmdGetRating.ExecuteReader())
                    {
                        while (reader.Read())
                        {
                            int rate = DB.RSFieldInt(reader, "Rating");
                            Rating.RatingOption actualRate = Rating.TryParse(rate);

                            customerRating =
                            new Rating(
                                DB.RSField(reader, "ItemCode"),
                                actualRate,
                                DB.RSField(reader, "Comments"),
                                DB.RSFieldDateTime(reader, "CreatedOn"),
                                DB.RSFieldInt(reader, "FoundHelpful"),
                                DB.RSFieldInt(reader, "FoundNotHelpful"),
                                DB.RSField (reader, "CustomerCode"),
                                DB.RSField(reader, "ContactSalutationCode"),
                                DB.RSField(reader, "ContactLastName"),
                                DB.RSField(reader, "ContactFirstName"), 
                                DB.RSField(reader, "ContactCode"),
                                DB.RSField(reader, "ContactSalutationCode"),
                                DB.RSField(reader, "ContactLastName"),
                                DB.RSField(reader, "ContactFirstName")
                            );
                        }
                    }
                }
            }

            return customerRating;
        }
    }

    public abstract class RatingSorter : IComparer<Rating>
    {
        #region IComparer<Rating> Members

        public virtual int Compare(Rating x, Rating y)
        {
            return 0;
        }

        #endregion
    }

   
    public class HelpfulToLessHelpfulRatingSorter : RatingSorter
    {
        public override int Compare(Rating x, Rating y)
        {
            return y.HelpfulCount.CompareTo(x.HelpfulCount);
        }
    }

    public class LessHelpfulToHelpfulRatingSorter : RatingSorter
    {
        public override int Compare(Rating x, Rating y)
        {
            return y.NotHelpfulCount.CompareTo(x .NotHelpfulCount);
        }
    }

    public class NewToOldRatingSorter : RatingSorter
    {
        public override int Compare(Rating x, Rating y)
        {
            return y.CreatedOn.CompareTo(x.CreatedOn);
        }
    }

    public class OldToNewRatingSorter : RatingSorter
    {
        public override int Compare(Rating x, Rating y)
        {
            return x.CreatedOn.CompareTo(y.CreatedOn);
        }
    }

    public class HighToLowRatingSorter : RatingSorter
    {
        public override int Compare(Rating x, Rating y)
        {
            return y.Rate.CompareTo(x.Rate);
        }
    }

    public class LowToHighRatingSorter : RatingSorter
    {
        public override int Compare(Rating x, Rating y)
        {
            return x.Rate.CompareTo(y.Rate);
        }
    }


    [Serializable, XmlRoot(ElementName = "ItemRating")]    
    public class RatingCollection
    {
        #region Variable Declaration

        private int _itemCounter = 0;
        private string _itemCode;
        private decimal _totalRating = decimal.Zero;
        private int _commentCount = 0;
        private decimal _averageRating = decimal.Zero;
        private List<Rating> _ratings = new List<Rating>();

        private decimal _terribleRatePercent = decimal.Zero;
        private decimal _badRatePercent = decimal.Zero;
        private decimal _okRatePercent = decimal.Zero;
        private decimal _goodRatePercent = decimal.Zero;
        private decimal _greatRatePercent = decimal.Zero;

        private decimal _terribleRateCount = decimal.Zero;
        private decimal _badRateCount = decimal.Zero;
        private decimal _okRateCount = decimal.Zero;
        private decimal _goodRateCount = decimal.Zero;
        private decimal _greatRateCount = decimal.Zero;

        private const string TERRIBLE_RATE = "Terrible";
        private const string BAD_RATE = "Bad";
        private const string OK_RATE = "OK";
        private const string GOOD_RATE = "Good";
        private const string GREAT_RATE = "Great";

        #endregion

        public RatingCollection()
        {
        }

        private const string AVERAGE_RATING_PROPERTY = "AverageRating";
        private const string ITEMS_PROPERTY = "Items";

        #region Properties

        [XmlElement(ElementName = "Counter")]
        public int ItemCounter
        {
            get { return _itemCounter; }
            set { throw new NotSupportedException(); }
        }

        [XmlElement(ElementName = "ItemCode")]
        public string ItemCode
        {
            get { return _itemCode; }
            set { throw new NotSupportedException(); }
        }
        
        [XmlElement(ElementName = "AverageRating")]
        public decimal AverageRating
        {
            get { return Math.Round(_averageRating,2); }
            set { throw new NotSupportedException(); }
        }

    
        [XmlElement(ElementName = "Count")]
        public int Count
        {
            get { return _ratings.Count; }
            set { throw new NotSupportedException(); }
        }

        [XmlArray(ElementName = "Ratings"),
         XmlArrayItem(ElementName = "Rating", Type = typeof(Rating))]
        public List<Rating> Items
        {
            get { return _ratings; }
        }

        [XmlElement(ElementName = "TerribleRatePercent")]
        public decimal TerribleRatePercent
        {
            get { return _terribleRatePercent; }
            set { throw new NotSupportedException(); }
        }

        [XmlElement(ElementName = "BadRatePercent")]
        public decimal BadRatePercent
        {
            get { return _badRatePercent; }
            set { throw new NotSupportedException(); }
        }

        [XmlElement(ElementName = "OkRatePercent")]
        public decimal OkRatePercent
        {
            get { return _okRatePercent; }
            set { throw new NotSupportedException(); }
        }

        [XmlElement(ElementName = "GoodRatePercent")]
        public decimal GoodRatePercent
        {
            get { return _goodRatePercent; }
            set { throw new NotSupportedException(); }
        }

        [XmlElement(ElementName = "GreatRatePercent")]
        public decimal GreatRatePercent
        {
            get { return _greatRatePercent; }
            set { throw new NotSupportedException(); }
        }

        public void Add(Rating item)
        {
            _totalRating += (decimal)item.Rate;
            _commentCount++;

            switch (item.Rate)
            {
                case Rating.RatingOption.Terrible:
                    _terribleRateCount++;
                    break;
                case Rating.RatingOption.Bad:
                    _badRateCount++;
                    break;
                case Rating.RatingOption.OK:
                    _okRateCount++;
                    break;
                case Rating.RatingOption.Good:
                    _goodRateCount++;
                    break;
                case Rating.RatingOption.Great:
                    _greatRateCount++;
                    break;
            }

            _ratings.Add(item);

            ComputeAverageRating();
            ComputeRatingPercents();
        }

        private void ComputeRatingPercents()
        {
            decimal factor = 100.0M;

            decimal allCount = (decimal)_ratings.Count;

            if (_terribleRateCount > decimal.Zero)
            {
                _terribleRatePercent = ( _terribleRateCount / allCount ) * factor;
            }

            if (_badRateCount > decimal.Zero)
            {
                _badRatePercent = (_badRateCount / allCount ) * factor;
            }

            if (_okRateCount > decimal.Zero)
            {
                _okRatePercent = ( _okRateCount / allCount ) * factor;
            }

            if (_goodRateCount > decimal.Zero)
            {
                _goodRatePercent = ( _goodRateCount / allCount ) * factor;
            }

            if (_greatRateCount > decimal.Zero)
            {
                _greatRatePercent = ( _greatRateCount / allCount ) * factor;
            }
        }

        public void ComputeAverageRating()
        {
            _averageRating = _totalRating / _ratings.Count;
        }

        public void Sort(RatingSorter sortingProvider)
        {
            _ratings.Sort(sortingProvider);
        }

        #endregion

        public static RatingCollection ForItem(string itemCode)
        {
            RatingCollection ratings = new RatingCollection();
            ratings._itemCode = itemCode;

            using (SqlConnection con = new SqlConnection(DB.GetDBConn()))
            {
                using (SqlCommand cmdGetRating = new SqlCommand("EcommerceGetRating", con))
                {
                    cmdGetRating.CommandType = CommandType.StoredProcedure;

                    SqlParameter paramItemCode = new SqlParameter("@ItemCode", SqlDbType.NVarChar, 30);
                    SqlParameter paramCustomerCode = new SqlParameter("@CustomerCode", SqlDbType.NVarChar, 30);
                    SqlParameter paramWebsiteCode = new SqlParameter("@WebsiteCode", SqlDbType.NVarChar, 30);
                    SqlParameter paramContactCode = new SqlParameter("@ContactCode", SqlDbType.NVarChar, 30);

                    paramItemCode.Value = itemCode;
                    paramCustomerCode.Value = DBNull.Value;
                    paramWebsiteCode.Value = InterpriseHelper.ConfigInstance.WebSiteCode;
                    paramContactCode.Value = DBNull.Value;

                    cmdGetRating.Parameters.Add(paramItemCode);
                    cmdGetRating.Parameters.Add(paramCustomerCode);
                    cmdGetRating.Parameters.Add(paramWebsiteCode);
                    cmdGetRating.Parameters.Add(paramContactCode);

                    con.Open();

                    using (IDataReader reader = cmdGetRating.ExecuteReader())
                    {
                        while (reader.Read())
                        {
                            ratings._itemCounter = DB.RSFieldInt(reader, "Counter");

                            int rate = DB.RSFieldInt(reader, "Rating");
                            Rating.RatingOption actualRate = Rating.TryParse(rate);

                            Rating itemRating =
                            new Rating(
                                DB.RSField(reader, "ItemCode"),
                                actualRate,
                                DB.RSField(reader, "Comments"),
                                DB.RSFieldDateTime(reader, "CreatedOn"),
                                DB.RSFieldInt(reader, "FoundHelpful"),
                                DB.RSFieldInt(reader, "FoundNotHelpful"), 
                                DB.RSField(reader, "CustomerCode"),
                                DB.RSField(reader, "ContactSalutationCode"),
                                DB.RSField(reader, "ContactLastName"),
                                DB.RSField(reader, "ContactFirstName"),
                                DB.RSField(reader, "ContactCode"),
                                DB.RSField(reader, "ContactSalutationCode"),
                                DB.RSField(reader, "ContactLastName"),
                                DB.RSField(reader, "ContactFirstName")
                            );

                            ratings.Add(itemRating);
                        }
                    }
                }
            }

            return ratings;
        }

        public string Serialize()
        {
            StringBuilder logSerialization = new StringBuilder();

            using (StringWriter sw = new StringWriter(logSerialization))
            {
                using (XmlWriter writer = new XmlTextWriter(sw))
                {
                    XmlSerializer serializer = new XmlSerializer(this.GetType());
                    serializer.Serialize(writer, this);
                }
            }

            return logSerialization.ToString();
        }

        public string ShowStars()
        {
            return AppLogic.GetString("ratings.cs.17", Customer.Current.SkinID, Customer.Current.LocaleSetting) + CommonLogic.BuildStarsImage(_averageRating, Customer.Current.SkinID);
        }

        public string ShowStars(string rate, int skinID)
        {
            decimal rateValue = decimal.Zero;
            switch (rate)
            {
                case TERRIBLE_RATE:
                    rateValue = 1M;
                    break;
                case BAD_RATE:
                    rateValue = 2M;
                    break;
                case OK_RATE:
                    rateValue = 3M;
                    break;
                case GOOD_RATE:
                    rateValue = 4M;
                    break;
                case GREAT_RATE:
                    rateValue = 5M;
                    break;                
            }

            return CommonLogic.BuildStarsImage(rateValue, skinID);
        }

        public string ShowStars(int rate)
        {
            return CommonLogic.BuildStarsImage((decimal)rate, Customer.Current.SkinID);
        }


        public virtual string GetNativeShortDateString(string sDateTimeString)
        {
            XSLTExtensionBase.InputValidator IV = new XSLTExtensionBase.InputValidator("GetNativeShortDateString");
            DateTime dt = IV.ValidateDateTime("DateTimeString", sDateTimeString);
            return Localization.ToNativeShortDateString(dt);
        }

        static public String LocateImageURL(String ImageName)
        {
            return AppLogic.LocateImageURL("skins/skin_" + Customer.Current.SkinID + "/images/" + ImageName);
        }

        public virtual string StringResource(String sStringResourceName)
        {
            XSLTExtensionBase.InputValidator IV = new XSLTExtensionBase.InputValidator("StringResource");
            String StringResourceName = IV.ValidateString("StringResourceName", sStringResourceName);
            if (AppLogic.AppConfigBool("ShowStringResourceKeys"))
            {
                return StringResourceName;
            }
            string result = String.Empty;
            if (StringResourceName.Length != 0)
            {
                result = AppLogic.GetString(StringResourceName, Customer.Current.SkinID, Customer.Current.LocaleSetting);
            }
            return result;
        }

        public string RateProductlink()
        {
            StringBuilder tmpS = new StringBuilder(50000);

            Rating rate = Rating.ByCustomer(Customer.Current, this.ItemCode);
            
            tmpS.Append(" | "+StringResource("ratings.cs.18") + " " + this.Count + " | ");

            if (rate != null)
            {
                tmpS.Append(" "+StringResource("ratings.cs.19") + ShowStars(rate.Rate.ToString(), Customer.Current.SkinID) + " | ");
            }

            
            if (AppLogic.AppConfigBool("RatingsCanBeDoneByAnons") || !Customer.Current.IsNotRegistered)
            {
                string ratePermissionTitle;

                if (this.Count == 0)
                {
                    ratePermissionTitle = StringResource("ratings.cs.26");
                }
                else
                {
                    if (rate!=null)
                    {
                        ratePermissionTitle = StringResource("ratings.cs.20");
                    }
                    else
                    {
                        ratePermissionTitle = StringResource("ratings.cs.21");
                    }
                }

                tmpS.Append("<a href=\"javascript:RateIt(" + CommonLogic.ParamsUSInt("ProductID") + ");\">" + StringResource("ratings.cs.25") + "</a> " + ratePermissionTitle + "");
                tmpS.Append("<SCRIPT LANGUAGE=\"javascript\">\n");
                tmpS.Append("	function RateIt(ProductID)\n");
                tmpS.Append("	{\n");
                tmpS.Append("		window.open('rateit.aspx?ProductID=' + ProductID + '&refresh=no&returnurl=" +
                    HttpContext.Current.Server.UrlEncode(CommonLogic.PageInvocation()) + "','ise" +
                    CommonLogic.GetRandomNumber(1, 100000).ToString() +
                    "','height=450,width=440,top=10,left=20,status=no,toolbar=no,menubar=no,scrollbars=yes,location=no')\n");
                tmpS.Append("	}\n");
                tmpS.Append("</SCRIPT>\n");
                tmpS.Append("</BR></BR>");
            }
            else
            {
                tmpS.Append("<B>" + StringResource("ratings.cs.22") + "</B>");
            }
            

            return tmpS.ToString();
        }

        public string ShowSortingOption()
        {
            StringBuilder tmpS = new StringBuilder(50000);

            Rating.RatingSortOrder OrderByIdx = (Rating.RatingSortOrder)CommonLogic.FormUSInt("RatingSortOrder");
            
            if (GetCommentsRowInfo(true) != 0 && GetCommentsRowInfo(false)!=0)
            {
                tmpS.Append("<form name=\"sortingComments\" method=\"POST\" >");
                tmpS.Append(AppLogic.GetString("ratings.cs.7", Customer.Current.SkinID, Customer.Current.LocaleSetting)+ " ");
                tmpS.Append("<select size=\"1\" name=\"RatingSortOrder\" onChange=\"document.sortingComments.submit();\">");
                tmpS.AppendFormat("<option value=\"{0}\" " + CommonLogic.IIF(OrderByIdx == Rating.RatingSortOrder.HelpfulToLessHelpful, " selected", "") + ">"+ StringResource("ratings.cs.1") +"</option>", (int)Rating.RatingSortOrder.HelpfulToLessHelpful);
                tmpS.AppendFormat("<option value=\"{0}\" " + CommonLogic.IIF(OrderByIdx == Rating.RatingSortOrder.LessHelpfulToHelpful, " selected", "") + ">"+ StringResource("ratings.cs.2") +"</option>", (int)Rating.RatingSortOrder.LessHelpfulToHelpful);
                tmpS.AppendFormat("<option value=\"{0}\" " + CommonLogic.IIF(OrderByIdx == Rating.RatingSortOrder.NewToOld, " selected", "") + ">" + StringResource("ratings.cs.3") + "</option>", (int)Rating.RatingSortOrder.NewToOld);
                tmpS.AppendFormat("<option value=\"{0}\" " + CommonLogic.IIF(OrderByIdx == Rating.RatingSortOrder.OldToNew, " selected", "") + ">" + StringResource("ratings.cs.4") + "</option>", (int)Rating.RatingSortOrder.OldToNew);
                tmpS.AppendFormat("<option value=\"{0}\" " + CommonLogic.IIF(OrderByIdx == Rating.RatingSortOrder.HighToLow, " selected", "") + ">" + StringResource("ratings.cs.5") + "</option>", (int)Rating.RatingSortOrder.HighToLow);
                tmpS.AppendFormat("<option value=\"{0}\" " + CommonLogic.IIF(OrderByIdx == Rating.RatingSortOrder.LowToHigh, " selected", "") + ">" + StringResource("ratings.cs.6") + "</option>", (int)Rating.RatingSortOrder.LowToHigh);
                tmpS.Append("</select>");
                tmpS.Append("</form>");
            }
            else
            {
                tmpS.Append(StringResource("ratings.cs.24"));
            }

            
           
            return tmpS.ToString();
        }

        public RatingCollection Page(int from, int to)
        {
            RatingCollection pagedRatings = new RatingCollection();

            int start = from-1;
            int end = to-1;
            while (start <= end)
            {
                pagedRatings.Add(_ratings[start]);
                start++;
            }
            pagedRatings._itemCounter = this._itemCounter;
            pagedRatings._averageRating = this._averageRating;
            pagedRatings._terribleRatePercent = this._terribleRatePercent;
            pagedRatings._badRatePercent = this._badRatePercent;
            pagedRatings._okRatePercent = this._okRatePercent;
            pagedRatings._goodRatePercent = this._goodRatePercent;
            pagedRatings._greatRatePercent = this._greatRatePercent;

            return pagedRatings;
        }

        public int CommentPageCounter()
        {
            int pagedExcess = 0;
            int pageCount = 0;

            int pagesize = AppLogic.AppConfigUSInt("RatingsPageSize");
            int pageNumber = CommonLogic.QueryStringUSInt("PageNumber");

            if (pagesize == 0) { pagesize = 5; }
            if (pageNumber == 0) { pageNumber = 1; }

            pageCount = this.Count / pagesize;

            if (this.Count > pagesize)
            {
                pagedExcess = this.Count % pagesize;

                if (pagedExcess != 0) 
                {
                    pageCount = this.Count / pagesize + 1;
                }              
            }
            else
            {
                pageCount = 1;
            }

            return pageCount;

        }

        public int GetCommentsRowInfo(bool isStartRow)
        {           
            int pagedExcess = 0;
            int pageCount = 0;
            int wholePage = 0;
            int start = 0;
            int stop = 0;
            int pagesize = AppLogic.AppConfigUSInt("RatingsPageSize");
            int pageNumber = CommonLogic.QueryStringUSInt("PageNumber");

            if (pagesize == 0) { pagesize = 5; }
            if (pageNumber == 0){pageNumber = 1;}

            //# of pages
            pageCount = this.Count / pagesize;
          

            //remainder of paged items
            if (this.Count > pagesize)
            {

                pagedExcess = this.Count % pagesize;

                //get the number of whole pages
                if (pagedExcess != 0) //if has remeainder
                {
                    pageCount = this.Count / pagesize + 1;
                    wholePage = pageCount - 1;

                    if (pageNumber > wholePage)
                    {
                        start = ((pageNumber - 1) * pagesize) + 1;
                        stop = ((pageNumber - 1) * pagesize) + pagedExcess;
                    }
                    else
                    {
                        start = ((pageNumber - 1) * pagesize) + 1;
                        stop = pageNumber * pagesize;
                    }
                }
                else
                {
                    //wholePage = pageCount;
                    start = ((pageNumber - 1) * pagesize) + 1;
                    stop = pageNumber * pagesize;
                }
            }
            else
            {
                pageCount = 1;

                start = ((pageNumber - 1) * pagesize) + 1;
                stop = pageNumber * this.Count;
            }

            if (isStartRow)
            {
                return start;
                
            }
            else
            {
                return stop;   
            }

        }

        public string GetPagingURL(int pagingNumber)
        {
            string currentURL = HttpContext.Current.Request.Url.PathAndQuery;
            string newQueryString = string.Empty;
            int pageNumber = CommonLogic.QueryStringUSInt("PageNumber");

            if (pageNumber == 0)
            {
                newQueryString = currentURL + "&PageNumber=" + pagingNumber;
            }
            else
            {
                string[] parts = currentURL.Split('&');
               int counter=0;
                foreach (string items in parts)
                {
                    string name=string.Empty;
                    string value = string.Empty;

                    string[] nameValuePair = items.Split('=');
                    if (nameValuePair.Length == 2)
                    {
                        
                        name = nameValuePair[0];

                        if (name.Equals("pagenumber", StringComparison.InvariantCultureIgnoreCase))
                        {
                            value = pagingNumber.ToString();
                        }
                        else
                        {
                            value = nameValuePair[1];
                        }
                    }
                    
                    if (!CommonLogic.IsStringNullOrEmpty(name) &&
                    !CommonLogic.IsStringNullOrEmpty(value))
                    {
                       

                        if (counter > 0)
                        {
                            newQueryString += "&" + name + "=" + value;
                        }
                        else
                        {
                            newQueryString += name + "=" + value;
                        }
                        
                    }
                    counter++;
                }
            }
            return newQueryString;
        }

        public string CommentPaging()
        {
            StringBuilder tmpS = new StringBuilder(50000);
            
            int pageNumber = CommonLogic.QueryStringUSInt("PageNumber");

            if (pageNumber == 0)
            {
                pageNumber = 1;
            }
            
            if (GetCommentsRowInfo(true) != 0 && GetCommentsRowInfo(false)!=0)
            {
                tmpS.AppendFormat(StringResource("ratings.cs.23") + " Comments | ", GetCommentsRowInfo(true), GetCommentsRowInfo(false), this.Count);
            }

           
            if (CommentPageCounter() > 1 && pageNumber > 1 && pageNumber <= CommentPageCounter())
            {
                tmpS.Append("<a href=\"" + GetPagingURL(pageNumber-1) + "\">" + StringResource("ratings.cs.8") + "</a> ");

            }

            if (GetCommentsRowInfo(true) != 0 && GetCommentsRowInfo(false) != 0)
            {
                for (int i = 1; i <= CommentPageCounter(); i++)
                {
                    
                    if (pageNumber == i)
                    {
                        tmpS.Append("<B>" + i + "</B> ");
                    }
                    else
                    {
                        tmpS.Append("<a href=\" " + GetPagingURL(i) + "\">" + i + "</a> ");
                    }

                }
            }                

            if (CommentPageCounter() > 1 && pageNumber < CommentPageCounter())
            {
                tmpS.Append(" <a href=\"" + GetPagingURL(pageNumber + 1) + "\">" + StringResource("ratings.cs.9") + "</a>");
            }

            return tmpS.ToString();
        }

        public string CommentVoting(string itemcode, string ratersCustomerId, string ratersContactId)
        {
            StringBuilder tmpS = new StringBuilder(50000);
            if (!Customer.Current.IsNotRegistered && (Customer.Current.CustomerCode != ratersCustomerId || Customer.Current.ContactCode != ratersContactId))
            {
                tmpS.Append(AppLogic.GetString("ratings.cs.27", Customer.Current.SkinID, Customer.Current.LocaleSetting));
                tmpS.Append("<INPUT TYPE=\"RADIO\" NAME=\"helpful_" + itemcode + "_" + ratersCustomerId + "\" onClick=\"return RateComment('" + itemcode + "','" + Customer.Current.CustomerID + "','Yes','" + ratersCustomerId + "','" + Customer.Current.ContactCode + "','" + ratersContactId  + "');\">");
                tmpS.Append("<FONT face=\"arial,helvetica\" size=1 color=\"#006600\">" + StringResource("ratings.cs.28") + "\n");
                tmpS.Append("<INPUT TYPE=\"RADIO\" NAME=\"helpful_" + itemcode + "_" + ratersCustomerId + "\" onClick=\"return RateComment('" + itemcode + "','" + Customer.Current.CustomerID + "','No','" + ratersCustomerId + "','" + Customer.Current.ContactCode + "','" + ratersContactId + "');\">");
                tmpS.Append("<FONT face=\"arial,helvetica\" size=1 color=\"#006600\">" + StringResource("ratings.cs.29") + "\n");

                tmpS.Append("<script type=\"text/javascript\">\n");
                tmpS.Append("function RateComment(ProductID,MyCustomerID,MyVote,RatersCustomerID,MyContactID,RatersContactID)\n");
                tmpS.Append("	{\n");
                tmpS.Append("	RateCommentFrm.location = 'RateComment.aspx?Productid=' + ProductID + '&VotingCustomerID=' + MyCustomerID + '&MyVote=' + MyVote + '&CustomerID=' + RatersCustomerID + '&VotingContactID=' + MyContactID + '&ContactID=' + RatersContactID\n");
                tmpS.Append("	}\n");
                tmpS.Append("</script>\n");
            }

            return tmpS.ToString();

        }


        public string Display(Customer viewingCustomer)
        {
            // check if we should sort
            // initially, not sorted....
            Rating.RatingSortOrder sortProcedure = (Rating.RatingSortOrder)CommonLogic.FormUSInt("RatingSortOrder");
            
            switch (sortProcedure)
            {
                case Rating.RatingSortOrder.HelpfulToLessHelpful: 
                    this.Sort(new HelpfulToLessHelpfulRatingSorter());
                    break;
                case  Rating.RatingSortOrder.LessHelpfulToHelpful: 
                    this.Sort(new LessHelpfulToHelpfulRatingSorter());
                    break;
                case Rating.RatingSortOrder.NewToOld :
                    this.Sort(new NewToOldRatingSorter());
                    break;
                case Rating.RatingSortOrder.OldToNew :
                    this.Sort(new OldToNewRatingSorter());
                    break;
                case Rating.RatingSortOrder.HighToLow:
                    this.Sort(new HighToLowRatingSorter());
                    break;
                case Rating.RatingSortOrder.LowToHigh:
                    this.Sort(new LowToHighRatingSorter());
                    break;
                default:
                    this.Sort(new HelpfulToLessHelpfulRatingSorter());
                    break;
            }

            
            RatingCollection ratingsToRender = this;
            ratingsToRender = Page(GetCommentsRowInfo(true), GetCommentsRowInfo(false));

            XmlDocument doc = new XmlDocument();
            doc.LoadXml(ratingsToRender.Serialize());

            XslCompiledTransform transform = new XslCompiledTransform(false);

            XsltArgumentList args = new XsltArgumentList();
            args.AddExtensionObject("urn:ise", this);

            XmlUrlResolver resolver = new XmlUrlResolver();
            resolver.Credentials = System.Net.CredentialCache.DefaultCredentials;

            XmlDocument batchDoc = new XmlDocument();

            string result = string.Empty;

            transform.Load(CommonLogic.SafeMapPath("XmlPackages/page.rating.xml.config"));

            using (MemoryStream strm = new MemoryStream())
            {
                transform.Transform(doc, args, strm);

                strm.Position = 0;
                using (StreamReader reader = new StreamReader(strm))
                {
                    result = reader.ReadToEnd();
                }
            }

            return result;
        }

        #region IEnumerable<Rating> Members

        public IEnumerator<Rating> All
        {
            get { return _ratings.GetEnumerator(); }
        }

        #endregion

    }



}







